﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using JQuery.WebKit.Common.Extenstions;
using JQuery.WebKit.WebCommon;
using JQuery.WebKit.Interfaces;

namespace JQuery.WebKit.Base
{
    public class WebScriptResourceCollection : CollectionBase
    {
        private IJPage _page;

        public WebScriptResourceCollection(IJPage page)
        {
            _page = page;
            _page.PreRenderComplete += new EventHandler(_page_PreRenderComplete);
        }

        void _page_PreRenderComplete(object sender, EventArgs e)
        {
            StringBuilder docReadySB = new StringBuilder();
            docReadySB.Append("$(document).ready(function() { ");

            StringBuilder windowLoadSB = new StringBuilder();
            windowLoadSB.Append("$(window).load(function() { ");

            StringBuilder simpleScriptSB = new StringBuilder();

            bool hasDocReady = false;
            bool hasWindowLoad = false;

            string updaterId = (string)_page.PageData["target"];
            JUpdater pnl = null;
            if (!string.IsNullOrEmpty(updaterId))
            {
                pnl = (JUpdater)(_page as Page).FindControlRecursive(updaterId, IDType.Client);
            }

            //int i = 0;
            //int c = base.List.Count;
            //while (i < c)
            //{
            //    WebScriptResource res = (WebScriptResource)base.List[i];
            //    if (!res.Script.EndsWith(".js") && !res.Script.EndsWith(".css"))
            //    {
            //        base.List.RemoveAt(i);
            //        base.List.Add(res);
            //        c--;
            //    }
            //    else
            //    {
            //        i++;
            //    }
            //}

            //WebScriptResource jsRes = new WebScriptResource()
            string jsCombinedRes = null;
            string cssCombinedRes = null;
            IList<WebScriptResource> dependencySorted = base.List.DependencySort<WebScriptResource>("Dependencies");

            IList<WebScriptResource> headerResources = new List<WebScriptResource>();
            foreach (WebScriptResource res in dependencySorted)
            {
                if (pnl != null && pnl.GetContainedChildren<Control>(item => item.ClientID == res.ControlID).Count == 0)
                {
                    continue;
                }
                if (res.Script.EndsWith(".js") || res.Script.EndsWith(".css"))
                {
                    if (!_page.IsPostBack && !_page.IsRefresh)
                    {
                        headerResources.Add(res);
                    }
                    else
                    {
                        HtmlUtil.RegisterResource(res.Type, res.Script, res.ResourceType, true);
                    }
                    //switch (res.ResourceType)
                    //{
                    //    case ResourceType.Javascript:
                    //        jsCombinedRes += ResManager.GetStringResource(res.Type.Assembly, res.Script);
                    //        break;
                    //    case ResourceType.Stylesheet:
                    //        cssCombinedRes += ResManager.GetStringResource(res.Type.Assembly, res.Script);
                    //        break;
                    //    default:
                    //        break;
                    //}

                }
                else
                {
                    switch (res.LoadType)
                    {
                        case LoadEvent.NA:
                            if (pnl == null && !_page.IsPostBack && !_page.IsRefresh)
                            {
                                HtmlUtil.RegisterScript((_page as Page), res.Type, res.Script, res.RegisterAtTheEnd);
                            }
                            else if (pnl != null)
                            {
                                pnl.AddBodyScript(res.Script);
                            }
                            break;
                        case LoadEvent.DocumentReady:
                            hasDocReady = true;
                            docReadySB.Append(res.Script);
                            break;
                        case LoadEvent.WindowLoad:
                            hasWindowLoad = true;
                            windowLoadSB.Append(res.Script);
                            break;
                        default:
                            break;
                    }
                }
            }
            HeadScriptManager.RegisterHeaderResourceList((_page as Page), typeof(IJPage), headerResources);
            if (!string.IsNullOrWhiteSpace(jsCombinedRes))
            {
                HtmlUtil.RegisterResource(typeof(JPage), jsCombinedRes, ResourceType.Javascript);
            }

            if (!string.IsNullOrWhiteSpace(cssCombinedRes))
            {
                HtmlUtil.RegisterResource(typeof(JPage), cssCombinedRes, ResourceType.Stylesheet);
            }

            if (hasDocReady)
            {
                docReadySB.Append(" });");
                if (pnl == null)
                {
                    HtmlUtil.RegisterScript((_page as Page), typeof(IJPage), docReadySB.ToString(), false);
                }
                else
                {
                    pnl.AddBodyScript(docReadySB.ToString());
                }
            }

            if (hasWindowLoad)
            {
                windowLoadSB.Append(" });");
                if (pnl == null)
                {
                    HtmlUtil.RegisterScript((_page as Page), typeof(IJPage), windowLoadSB.ToString(), false);
                }
                else
                {
                    pnl.AddBodyScript(windowLoadSB.ToString());
                }
            }
        }

        public WebScriptResource this[int index]
        {
            get
            {
                return ((WebScriptResource)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(WebScriptResource value)
        {
            if (List.Contains(value))
            {
                return -1;
            }
            //value.Page = _page;
            return (List.Add(value));
        }

        public int Add(Type controlType, string resourceName, ResourceType resourceType)
        {
            WebScriptResource res = new WebScriptResource(controlType, null, resourceType, resourceName);
            return Add(res);
        }

        public int IndexOf(WebScriptResource value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, WebScriptResource value)
        {
            if (List.Contains(value))
            {
                return;
            }
            //value.Page = _page;
            List.Insert(index, value);
        }

        public void Remove(WebScriptResource value)
        {
            List.Remove(value);
        }

        public bool Contains(WebScriptResource value)
        {
            return (List.Contains(value));
        }

        protected override void OnRemove(int index, Object value)
        {
            // Insert additional code to be run only when removing values.
        }

        protected override void OnValidate(Object value)
        {
            if (value.GetType() != typeof(WebScriptResource))
                throw new ArgumentException("value must be of type WebScriptResource.", "value");
        }

        protected override void OnInsert(int index, object value)
        {
            if (base.List.Contains(value))
            {
                return;
            }
            base.OnInsert(index, value);
        }

        protected override void OnSet(int index, object oldValue, object newValue)
        {
            if (base.List.Contains(newValue))
            {
                return;
            }
            base.OnSet(index, oldValue, newValue);
        }
    }
}
